package cj.primariaiquest.ws.endpoint;

import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;

import cj.primariaiquest.model.Department;
import cj.primariaiquest.schemas.CancelTicketRequest;
import cj.primariaiquest.schemas.ObjectFactory;
import cj.primariaiquest.schemas.TicketRequest;
import cj.primariaiquest.schemas.TicketResponse;
import cj.primariaiquest.ws.exceptions.InvalidDepartmentException;
import cj.primariaiquest.ws.exceptions.InvalidTicketNumber;
import cj.primariaiquest.ws.exceptions.OutOfNumbersException;
import cj.primariaiquest.ws.service.TicketService;

/**
 * Endpoint class used to handle request messages.
 * 
 * @author georgian.parvu
 * 
 */
@Endpoint
public class TicketEndpoint {

    private final TicketService ticketService;
    private final ObjectFactory objectFactory;

    public TicketEndpoint(TicketService ticketService,
	    ObjectFactory objectFactory) {
	super();
	this.ticketService = ticketService;
	this.objectFactory = objectFactory;
    }

    /**
     * This method processes ticketRequests. Calls the ticket service and
     * returns a response with the ticket number.
     * 
     * @param ticketRequest
     *            TicketRequest converted from request message
     * @return TicketResponse
     * @throws OutOfNumbersException
     *             if no more numbers are available for the required department
     * @throws InvalidDepartmentException
     *             if the department provided is invalid
     */
    @PayloadRoot(localPart = "TicketRequest", namespace = "http://www.primariaIquest.cj/schemas")
    public TicketResponse getTicketNumber(TicketRequest ticketRequest)
	    throws OutOfNumbersException, InvalidDepartmentException {
	TicketResponse ticketResponse = objectFactory.createTicketResponse();

	Department dep = validateDepartment(ticketRequest.getDepartment());

	ticketResponse.setNumber(ticketService.getNextNumber(dep));

	return ticketResponse;
    }

    /**
     * This method processes CancelTicketRequests. Calls the ticket service and
     * send the canceled ticket to the message flow.
     * 
     * 
     * @param cancelTicketRequest
     *            CancelTicketRequest converted from request message
     * @throws InvalidDepartmentException
     *             if the department provided is invalid
     * @throws InvalidTicketNumber
     *             if the ticket number provided is invalid
     */
    @PayloadRoot(localPart = "CancelTicketRequest", namespace = "http://www.primariaIquest.cj/schemas")
    public void cancelTicket(CancelTicketRequest cancelTicketRequest)
	    throws InvalidDepartmentException, InvalidTicketNumber {

	Department dep = validateDepartment(cancelTicketRequest.getDepartment());

	ticketService.placeCanceledTicket(dep, cancelTicketRequest.getNumber());
    }

    /**
     * Validates the given department. If it's not valid an
     * InvalidDepartmentException will be thrown
     * 
     * @param department
     *            String representing the department to validate
     * @return Department the corresponding department enum.
     * @throws InvalidDepartmentException
     *             if it's no t a valid department
     */
    private Department validateDepartment(final String department)
	    throws InvalidDepartmentException {
	Department dep = null;
	try {
	    dep = Department.valueOf(department);
	} catch (Exception e) {
	    throw new InvalidDepartmentException(
		    "The department you provided is invalid");
	}
	return dep;
    }
}
